package com.load.parsers;

import japa.parser.ast.CompilationUnit;
import japa.parser.ast.body.*;
import japa.parser.ast.stmt.*;
import japa.parser.ast.visitor.VoidVisitorAdapter;

import com.database.objects.*;
import com.database.objects.Class;

public class MethodParser {

	public static void addMethods(CompilationUnit compilation, Class clazz) {
		ClassVisitor classVisitor = new ClassVisitor();
		classVisitor.visit(compilation, clazz);
	}

	private static class ClassVisitor extends VoidVisitorAdapter<Class> {
		@Override
		public void visit(ClassOrInterfaceDeclaration classFile, Class clazz) {
			super.visit(classFile, clazz);
			if (clazz.getName().equals(classFile.getName())) {
				MethodVisitor methodVisitor = new MethodVisitor();
				methodVisitor.visit(classFile, clazz);
			}
		}
	}

	private static class MethodVisitor extends VoidVisitorAdapter<Class> {

		@Override
		public void visit(MethodDeclaration methodFile, Class clazz) {
			super.visit(methodFile, clazz);
			Method method = new Method(methodFile.getName(), methodFile.getParameters(), clazz.getStatus(), clazz);
			BlockStmt body = methodFile.getBody();
			String content = body != null ? body.toString() : "";
			method.setContent(content);
			clazz.addChild(method);

			VariableVisitor variableVisitor = new VariableVisitor();
			variableVisitor.visit(methodFile, method);

			DecisionVisitor decisionVisitor = new DecisionVisitor();
			decisionVisitor.visit(methodFile, method);
		}

	}

	private static class VariableVisitor extends VoidVisitorAdapter<Method> {
		@Override
		public void visit(VariableDeclaratorId variableFile, Method method) {
			super.visit(variableFile, method);
			method.addVariable(new Variable(variableFile.toString()));
		}
	}

	private static class DecisionVisitor extends VoidVisitorAdapter<Method> {

		@Override
		public void visit(IfStmt ifFile, Method method) {
			super.visit(ifFile, method);
			method.addCyclomatic();
		}

		@Override
		public void visit(SwitchStmt switchFile, Method method) {
			super.visit(switchFile, method);
			method.addCyclomatic(switchFile.getEntries().size());
		}

		@Override
		public void visit(ForeachStmt forFile, Method method) {
			super.visit(forFile, method);
			method.addCyclomatic();
		}

		@Override
		public void visit(ForStmt forFile, Method method) {
			super.visit(forFile, method);
			method.addCyclomatic();
		}

		@Override
		public void visit(DoStmt doFile, Method method) {
			super.visit(doFile, method);
			method.addCyclomatic();
		}

		@Override
		public void visit(WhileStmt whileFile, Method method) {
			super.visit(whileFile, method);
			method.addCyclomatic();
		}

	}

}